package com.eqgis.eqtool.cfg;

import android.content.Context;
import android.content.res.AssetManager;
import android.util.Log;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;

/**
 * 本地配置管理工具
 *      主要用于读取本地的cfg配置文件
 * @create by tanyx 2021年6月29日11:38:15
 */
public class LocalConfigManager {
    private static LocalConfigManager localConfigManager = null;
    private static final String TAG = LocalConfigManager.class.getSimpleName();
    private String charsetName;;
    private boolean isInAssets = false;
    private HashMap<String,String> resultMap = new HashMap<String, String>();
    private String assetsPath = "app.cfg";
    private String localPath;

    LocalConfigManager() {
    }

    private LogListener logListener;

    /**
     * 设置日志监听
     * @param logListener
     */
    public void setLogListener(LogListener logListener) {
        this.logListener = logListener;
    }

    public interface LogListener{
        void loge(String msg);
        void logi(String msg);
    }

    public static LocalConfigManager getInstance(){
        if (localConfigManager == null) {
            synchronized (LocalConfigManager.class) {
                if(localConfigManager == null) {
                    localConfigManager = new LocalConfigManager();
                }
            }
        }
        return localConfigManager;
    }

    /**
     * 加载配置
     * @param context
     * @return
     */
    public boolean loadConfig(Context context) {
        //清空结果
        resultMap.clear();

        InputStream is = createFisByLocalhost(localPath);
        if (is == null){
            Log.i(TAG, "LocalPath was error.");
            if (logListener!=null){
                logListener.logi(TAG+"  LocalPath was error. ");
            }
            //使用assets路径
            try {
                is = createIsByAssets(context);
            } catch (IOException e) {
                Log.e(TAG, "AssetsPath was error.", e);
                if (logListener!=null){
                    logListener.loge(TAG+"  AssetsPath was error. "+ e.toString());
                }
                return false;
            }
        }

        //未设置编码格式，则使用默认方式判断
        if (charsetName == null){
            try {
                charsetName = checkCharsetName(is);
                if (logListener!=null){
                    logListener.logi(TAG+"  The CharsetName of cfg is "+ charsetName);
                }
            } catch (IOException e) {
                Log.e(TAG, "CharsetName : ",e);
                if (logListener!=null){
                    logListener.loge(TAG+"  CharsetName: "+ e.toString());
                }
            }
        }

        InputStreamReader isr;
        try {
            isr = new InputStreamReader(is, charsetName);
        } catch (UnsupportedEncodingException e) {
            Log.e(TAG, "CharsertName was error.", e);
            if (logListener!=null){
                logListener.loge(TAG+"  CharsertName was error."+ e.toString());
            }
            return false;
        }

        BufferedReader br = new BufferedReader(isr);

        String line = "";
        try {
            while ((line = br.readLine()) != null){
                if (line.lastIndexOf("---") < 0){
                    //逐行读取，判断当前行内容，存入hashMap
                    saveToMap(line);
                }
            }
        }catch (IOException e) {
            Log.e(TAG, "IOException.", e);
            if (logListener!=null){
                logListener.loge(TAG+"  IOException."+ e.toString());
            }
        }


        Log.i(TAG, "Success: Count = "+resultMap.size());
        if (logListener!=null){
            logListener.logi(TAG+"  Success: Count = "+resultMap.size());
        }

        try {
            br.close();
            isr.close();
            is.close();
        } catch (IOException e) {
            Log.e(TAG, "IOException.", e);
            if (logListener!=null){
                logListener.loge(TAG+"  IOException." + e.toString());
            }
        }
        return true;
    }

    private String checkCharsetName(InputStream inputStream) throws IOException {
        byte[] head = new byte[3];
        inputStream.read(head);
        String charsetName = "GBK";//或GB2312，即ANSI
        if(head[0]==-17 && head[1]==-69 && head[2] ==-65)
            charsetName = "UTF-8"; //UTF-8-BOM
        else if (head[0]==35 && head[1]==-24 && head[2] ==-65)
            charsetName = "UTF-8";
        return charsetName;
    }

    private void saveToMap(String line) {
        //若line为“#”开头，则为注释行，跳过不存
        if (line.startsWith("#")){
            return;
        }
        //去掉头尾空白符
//        line.trim();
        String[] split = line.split("=");
        if (split.length == 2){
            resultMap.put(split[0].trim(),split[1].trim());
        }
    }



    private FileInputStream createFisByLocalhost(String localPath){
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(localPath);
        } catch (Exception e) {
            Log.e(TAG, "localPath is not exist.");
            if (logListener!=null){
                logListener.loge(TAG+"  localPath is not exist.");
            }
            return null;
        }
        return fis;
    }

    private InputStream createIsByAssets(Context context) throws IOException {
        AssetManager mAssetManger = context.getAssets();
        InputStream inputStream = mAssetManger.open(assetsPath);
        return inputStream;
    }


    /**
     * 检测参数是否为NULL
     * @param object
     * @return
     */
    private boolean checkParaIsNotNull(Object object){
        if (object == null){
            return false;
        }
        return true;
    }

    public String getCharsetName() {
        return charsetName;
    }

    public void setCharsetName(String charsetName) {
        this.charsetName = charsetName;
    }


    public void setLocalPath(String localPath) {
        this.localPath = localPath;
    }

    public void setAssetsPath(String assetsPath){
        this.assetsPath = assetsPath;
    }

    public HashMap<String, String> getResultMap() {
        return resultMap;
    }
}
